/*
 * @Date: 2023-12-18 17:56:34
 * @LastEditors: 玄绮 shijiahansi@qq.com
 * @LastEditTime: 2024-04-13 13:00:17
 * @FilePath: \server\src\server\app\ChatSessionManager.cpp
 */
#include "ChatSessionManager.h"

#include <system/System.h>
// #include <packet/message/Message.h>

ChatSessionManager::ChatSessionManager() {
}

ChatSessionManager::~ChatSessionManager() {
}

void ChatSessionManager::login(ChatSession::SharedPtr session) {
    sessions.emplace(session->myself().userid(), session);
    std::clog << "login  :" << session->myself().userid()<< std::endl;

    auto  userId = session->myself().userid();
    
    auto& queue  = getMessageQueue(userId);
    while (!queue.empty()) {
        auto _msg = queue.front();
        session->deliver(_msg);
        queue.pop();
    }
    // 发送信号
    signalUserLogin(userId, session);
}

void ChatSessionManager::unlogin(ChatSession::SharedPtr session) {
    unlogin(session->myself().userid());
}

void ChatSessionManager::unlogin(std::string userId) {
    auto session = sessions.at(userId);
    sessions.erase(userId);
    std::clog << "unlogin:" << userId << std::endl;

    // 发送信号
    signalUserUnLogin(userId, session);
}

void ChatSessionManager::sendMessage(data::Message msg) {
    std::string userId = msg.to_user_id();

    auto& queue = getMessageQueue(userId);
    queue.push(msg);

    if (isLogin(userId)) {
        auto session = getSession(userId);
        while (!queue.empty()) {
            auto _msg = queue.front();
            session->deliver(_msg);
            queue.pop();
        }
    }
}

ChatSession::SharedPtr ChatSessionManager::getSession(std::string userId) {
    return sessions.at(userId);
}

ChatSessionManager::MessageQueue& ChatSessionManager::getMessageQueue(std::string userId) {
    // TODO: 在此处插入 return 语句
    return messageQueues[userId];
}

bool ChatSessionManager::isLogin(std::string userId) const {
    try {
        auto a = sessions.at(userId);
        return true;
    }
    catch (const std::out_of_range&) {
        return false;
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << '\n';
    }

    return false;
}
